var dir = process.argv[2], targetDir = process.argv[3], thumbDir = process.argv[4];
var fs = require('fs'), path = require('path');
[dir, targetDir, thumbDir].forEach((x, i) => {
    if (!x || !fs.existsSync(x) || !fs.lstatSync(x).isDirectory()) {
        console.log('wrong argv[', i, ']:', x);
        console.log('process.argv:', process.argv);
        console.log('maybe not using " node xx.js dir targetDir thumbDir" ?');
        process.exit();
    }
})
    
var db = require('../db/index.js').get();
var configCl = db.config, directoryCl = db.directory, imageCl = db.image;

var now = Date.now(), _ui = 0;

var recordJSONPath = path.join(targetDir, '../', 'log.json');

var doneRes = fs.existsSync(recordJSONPath) ? JSON.parse(fs.readFileSync(recordJSONPath).toString()) : {};
var thread_count = 1;

function linearPromise(fns) {
    var cur = Promise.resolve();
    fns.forEach(function(fn) {
        cur = cur.then(fn);
    })
    return cur;
}

db.config.getValue('root_dir')
.then(null, () => {
    return directoryCl.create('Root').then(doc => {
        return db.config.setConfig('root_dir', doc._id)
        .then(function(c) {
            return Promise.resolve(c.value);
        });
    })
})
.then(_id => {
    function parseDirectroy(cur_path, parent_id) {
        console.log('handle dir:', cur_path);
        var nextDir = [], dirname = path.basename(cur_path);
        return directoryCl.read(parent_id).then(function(doc) {
            return directoryCl.findOne()
            .where('_id').in(doc.next)
            .where('name').equals(dirname)
            .then(target => {
                if (!target) {
                    return directoryCl.create(dirname)
                    .then(function(doc) {
                        // add to parent_id
                        return directoryCl.addNext(parent_id, [doc._id])
                        .then(function() {
                            return Promise.resolve(doc);
                        });
                    });
                } else {
                    return Promise.resolve(target);
                }
            })
        })
        .then(function(doc) {
            // read dir
            return new Promise((resolve, reject) => {
                fs.readdir(cur_path, function(err, arr) {
                    if (err) {
                        console.log(err);
                        return reject(err);
                    }
                    resolve({doc, arr});
                })
            })
        })
        .then(({doc, arr}) => {
            // create all image resource
            var images = arr.map(x => {
                var abs = path.join(cur_path, x);
                var extname = path.extname(abs);
                var state = fs.lstatSync(abs);
                if (state.isDirectory()) {
                    nextDir.push(abs);
                    return null;
                } else {
                    return /^\.(jpg|jpeg|png|webp|gif|bmp|svg)$/i.test(extname) ? {abs, state, x, extname} : null;
                }
            })
            .filter(x => x);
            var len = images.length, c = 0;
            return new Promise((resolve, reject) => {
                var next = function() {
                    if (c == len) {
                        resolve();
                        return;
                    }
                    if (!images.length) {
                        return;
                    }
                    var {abs, state, x, extname} = images.shift();
                    console.log('handle image:', abs);
                    if (abs in doneRes) {
                        console.log(`${abs} has done`);
                        c++;
                        return next();
                    }
                    imageCl.createFromFile({
                        size: state.size,
                        path: abs
                    }, {
                        name: x,
                        srcName: "am_" + (now + _ui++).toString(16) + extname,
                        targetDir, thumbDir
                    }).then(function(imgDoc) {
                        imgDoc.baseInfo.createDate = (state.birthtime || state.mtime || state.atime || state.ctime || new Date()).getTime();
                        doc.content.push(imgDoc._id);
                        return imgDoc.save();
                    }).then(imgDoc => {
                        c++;
                        doneRes[abs] = true;
                        next();
                    });
                };

                for (var i = 0; i < thread_count; i++) {
                    next();
                }

            }).then(function() {
                return doc.save();
            });
        })
        .then(function(doc) {
            var cur = Promise.resolve();
            nextDir.map(abs => {
                return function() {
                    return parseDirectroy(abs, doc._id);
                }
            }).forEach(fn => {
                cur = cur.then(fn);
            });
            return cur;
        })
        .then(x => {
            doneRes[cur_path] = true;
        });
    }

    return parseDirectroy(dir, _id);

})
.then(x => {
    console.log('operation done. --' + (Date.now() - now) + 'ms--');
    console.log('log file: ', recordJSONPath);
    fs.writeFileSync(recordJSONPath, JSON.stringify(doneRes, null, 2));
    process.exit();
}, function(err) {
    console.log('log file: ', recordJSONPath);
    fs.writeFileSync(recordJSONPath, JSON.stringify(doneRes, null, 2));
    console.log(err);
})
